function [pca_tr_data, tr_labels, pca_te_data, te_labels, pc] = ...
         perform_pca(X1train, X2train, ytrain, gidtrain, test_group_id, k)
%perform_pca Runs svm on the data and returns the data based on the
%            number of principal component required - k.
%            1. First, the data is splitted to train and test group.
%            2. The data is sphered - i.e for each attribute - the mean is 
%               subtructed and devided by the deviation. TODO: we might use
%               another normalization here - but then we won't be able to
%               use "princomp".
%            3. The test is sphered according to the data parameters.
%            4. PCA is computed.
%            5. Data is normalized and then test is normalized accordingly.
%               This is step is important for svm - not neccesarily for
%               trees.
%
%           For reference:
%               http://blog.explainmydata.com/2012/07/should-you-apply-pca-to-your-data.html
%               http://matlabdatamining.blogspot.co.il/2010/02/principal-components-analysis.html
            
    diff = abs(X1train - X2train);
    row_diff = diff';
    
    % split the data
    tr_data = row_diff(gidtrain~=test_group_id,:);
    te_data = row_diff(gidtrain==test_group_id,:);
    tr_labels = ytrain(gidtrain~=test_group_id);
    te_labels = ytrain(gidtrain==test_group_id);
    
    % Standardized the matrices
    [tr_data, tr_mean, tr_dev] = zscore(tr_data);
    te_data = standardized_mat(te_data, tr_mean, tr_dev);
    
    % pca on data then on test
    [pc, pca_tr_data] = princomp(tr_data, 'econ');
    
    
    pca_tr_data = pca_tr_data(:, 1:k);
    pca_te_data = te_data * pc(:, 1:k);
    
    % lastly - we normalize the pca output. Test set is normalized
    % based on the training set.
    [pca_tr_data, norm_params] = norm_data_col2(pca_tr_data);
    [pca_te_data, ~] = norm_data_col2(pca_te_data, norm_params);
end

